package com.zheng.oa.admin.controller.hr;

import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zheng.common.base.BaseController;
import com.zheng.common.util.Pagination;
import com.zheng.common.util.PoiUtil;
import com.zheng.common.util.PropertiesFileUtil;
import com.zheng.hr.dao.model.HrApproval;
import com.zheng.hr.dao.model.HrAttendance;
import com.zheng.hr.dao.model.HrCheckin;
import com.zheng.hr.rpc.api.HrApprovalService;
import com.zheng.hr.rpc.api.HrAttendanceService;
import com.zheng.hr.rpc.api.HrCheckinService;
import com.zheng.oa.common.constant.OaResult;
import com.zheng.oa.common.constant.OaResultConstant;
import com.zheng.upms.dao.model.UpmsOrganization;
import com.zheng.upms.rpc.api.UpmsOrganizationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

//import com.zheng.hr.dao.model.HrAttendance;
//import com.zheng.hr.rpc.api.HrAttendanceService;

/**
 * Created by IntelliJ IDEA.
 * User: xinqi
 * Date: 2017/11/16
 * Time: 11:17
 */
@Controller
@Api(value = "数据字典管理", description = "数据字典管理")
@RequestMapping("/oa/hr/attendance")
public class HrAttendanceController extends BaseController {
    @Autowired
    private HrAttendanceService attendanceService;
    @Autowired
    private HrApprovalService approvalService;
    @Autowired
    private UpmsOrganizationService organizationService;
    @Autowired
    private HrCheckinService checkinService;
    //线程安全的integer变量
    private static AtomicInteger synchronizeNum = new AtomicInteger(0);

    @RequiresPermissions("oa:hr:attendance:read")
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model) {
        return "/manage/hr/attendance/index.jsp";
    }

    @RequiresPermissions("oa:hr:attendance:read")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public Object list(@RequestParam(required = false, defaultValue = "1", value = "pageNumber") int pageNumber,
                       @RequestParam(required = false, defaultValue = "10", value = "pageSize") int pageSize,
                       @RequestParam(required = false, value = "sortName") String sortName,
                       @RequestParam(required = false, value = "sortOrder") String sortOrder,
                       @RequestParam(required = false, value = "isAdministration") boolean isAdministration,
                       HrAttendance attendance) {
        String organizationId = getOrganizationId(isAdministration);
        attendance.setPagination(new Pagination(pageNumber, pageSize, sortOrder, sortName));
        List<Map<String, Object>> rows = attendanceService.selectAttendancePage(attendance, organizationId);
        Integer total = attendanceService.selectAttendancePageCount(attendance, organizationId);
        Map<String, Object> result = new HashMap<>();
        result.put("rows", rows);
        result.put("total", total);
        return result;
    }

    private String getOrganizationId(boolean isAdministration) {
        String organizationId = "";
        String weekOrganizationId = PropertiesFileUtil.getInstance().get("weekOrganizationId");
        if (isAdministration) {
            List<Integer> ids = new ArrayList<>();
            for (String idStr : weekOrganizationId.split(",")) {
                ids.add(Integer.parseInt(idStr));
            }
            List<UpmsOrganization> organizations = organizationService.selectList(new EntityWrapper<UpmsOrganization>().notIn("organization_id", ids));
            for (int i = 0; i < organizations.size(); i++) {
                if (organizations.size() == i + 1) {
                    organizationId += organizations.get(i).getOrganizationId().toString();
                } else {
                    organizationId += organizations.get(i).getOrganizationId().toString() + ",";
                }
            }
        } else {
            organizationId = weekOrganizationId;
        }
        return organizationId;
    }

    @ApiOperation(value = "导出考勤记录")
    @RequiresPermissions("oa:hr:attendance:export")
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public void export(HrAttendance attendance, boolean isAdministration, HttpServletResponse response) throws Exception {
        String organizationId = getOrganizationId(isAdministration);
        List<Map<String, Object>> maps = attendanceService.selectAttendancePage(attendance, organizationId);
        Date time = attendance.getTime();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        String title = year + "年" + month + "月出勤情况";
        for (Map<String, Object> map : maps) {
            //将map转换为实体类
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(map));
            HrAttendance userAttendance = jsonObject.toJavaObject(HrAttendance.class);
            StringBuilder details = new StringBuilder();
            StringBuilder remark = new StringBuilder();

            Double leaveDays = userAttendance.getLeaveDays();
            Double annualLeaveDays = userAttendance.getAnnualLeaveDays();
            Double normalLeaveDays = userAttendance.getNormalLeaveDays();
            Double maritalLeaveDays = userAttendance.getMaritalLeaveDays();
            Double maternityLeaveDays = userAttendance.getMaternityLeaveDays();
            Double offLeaveDays = userAttendance.getOffLeaveDays();
            Double otherLeaveDays = userAttendance.getOtherLeaveDays();
            Double paternityLeaveDays = userAttendance.getPaternityLeaveDays();
            Double sickLeaveDays = userAttendance.getSickLeaveDays();
            Integer exceptionCount = userAttendance.getExceptionCount();
            String attendanceRemark = userAttendance.getRemark();
            Double exceptionDays = userAttendance.getExceptionDays();
            map.put("exception_days", exceptionDays + "天");
            Double supposedDays = userAttendance.getSupposedDays();
            map.put("supposed_days", supposedDays + "天");
            Double actualDays = userAttendance.getActualDays();
            map.put("actual_days", actualDays + "天");
            JSONObject remarkJson = JSONObject.parseObject(attendanceRemark);
            if (exceptionCount > 0) {
                Integer lateCount = remarkJson.getInteger("lateCount");
                Integer notCheckCount = remarkJson.getInteger("notCheckCount");
                //请假转换信息

                if (lateCount > 0) {
                    details.append("迟到或早退:");
                    details.append(lateCount);
                    details.append("次;");
                }
                if (notCheckCount > 0) {
                    if (isAdministration) {
                        details.append("忘记打卡:");
                    } else {
                        details.append("未打卡:");
                    }
                    details.append(notCheckCount);
                    details.append("次;");
                }

            }
            Double yearLeaveErrorDays = remarkJson.getDouble("yearLeaveErrorDays");
            Double offLeaveErrorDays = remarkJson.getDouble("offLeaveErrorDays");
            if (yearLeaveErrorDays != null && yearLeaveErrorDays > 0) {
                remark.append("年假不足变更为事假:");
                remark.append(yearLeaveErrorDays);
                remark.append("天;");
            }
            if (offLeaveErrorDays != null && offLeaveErrorDays > 0) {
                remark.append("调休假不足变更为事假:");
                remark.append(offLeaveErrorDays);
                remark.append("天;");
            }
            if (offLeaveDays > 0) {
                remark.append("调休");
                remark.append(offLeaveDays);
                remark.append("天 ");
            }
            if (annualLeaveDays > 0) {
                remark.append("年假");
                remark.append(annualLeaveDays);
                remark.append("天 ");
            }
            if (leaveDays > 0) {
                if (normalLeaveDays > 0) {
                    details.append("事假");
                    details.append(normalLeaveDays);
                    details.append("天 ");
                }
                if (sickLeaveDays > 0) {
                    details.append("病假");
                    details.append(sickLeaveDays);
                    details.append("天 ");
                }
                if (maritalLeaveDays > 0) {
                    details.append("婚假");
                    details.append(maritalLeaveDays);
                    details.append("天 ");
                }
                if (maternityLeaveDays > 0) {
                    details.append("产假");
                    details.append(maternityLeaveDays);
                    details.append("天 ");
                }
                if (paternityLeaveDays > 0) {
                    details.append("陪产假");
                    details.append(paternityLeaveDays);
                    details.append("天 ");
                }
                if (otherLeaveDays > 0) {
                    details.append("其他假期");
                    details.append(otherLeaveDays);
                    details.append("天 ");
                }
            }
            //备注情况
            JSONArray unusualArray = remarkJson.getJSONArray("unusualArray");
            if (unusualArray != null && unusualArray.size() > 0) {
                String unusual = "非常用设备信息:";
                for (int i = 0; i < unusualArray.size(); i++) {
                    unusual += unusualArray.getString(i);
                    unusual += "；";
                }
                remark.append(unusual);
            }
            if (details.length() < 1) {
                details = new StringBuilder("全勤");
            }
            map.put("details", details.toString());
            map.put("remark", remark.toString());
        }
        if (isAdministration) {
            //行政部门添加物业人员
            Map<String, Object> addMap = new HashMap<>();
            addMap.put("realname", "刘运生");
            addMap.put("joined_time", "2017-11-20");
            addMap.put("details", "全勤");
            addMap.put("organizationName", "物业部");
            maps.add(addMap);
            addMap = new HashMap<>();
            addMap.put("realname", "俎国友");
            addMap.put("joined_time", "2018-01-14");
            addMap.put("details", "全勤");
            addMap.put("organizationName", "物业部");
            maps.add(addMap);
            addMap = new HashMap<>();
            addMap.put("realname", "姬剑波");
            addMap.put("joined_time", "1997-01-01");
            addMap.put("details", "全勤");
            addMap.put("organizationName", "董办");
            maps.add(addMap);
            maps.sort(new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    Object organizationObj = o1.get("organizationName");
                    String wuYe = "物业部";
                    if (wuYe.equals(organizationObj.toString())) {
                        return 1;
                    }
                    return -1;
                }
            });
        }
        List<ExcelExportEntity> entities = new ArrayList<>();
        ExcelExportEntity entity = new ExcelExportEntity();
        entity.setKey("joined_time");
        entity.setName("入职时间");
        entities.add(entity);
        entity = new ExcelExportEntity();
        entity.setKey("realname");
        entity.setName("员工");
        entities.add(entity);
        entity = new ExcelExportEntity();
        entity.setKey("organizationName");
        entity.setName("部门名称");
        entities.add(entity);
        if (isAdministration) {
            entity = new ExcelExportEntity();
            entity.setKey("details");
            entity.setName(month + "月出勤情况");
            entity.setWidth(50);
            entities.add(entity);
        } else {
            entity = new ExcelExportEntity();
            entity.setKey("supposed_days");
            entity.setName("应打卡天数");
            entities.add(entity);
            entity = new ExcelExportEntity();
            entity.setKey("exception_days");
            entity.setName("未打卡天数");
            entities.add(entity);
            entity = new ExcelExportEntity();
            entity.setKey("actual_days");
            entity.setName("实际打卡天数");
            entities.add(entity);
            entity = new ExcelExportEntity();
            entity.setKey("details");
            entity.setName("出勤情况");
            entity.setWidth(50);
            entities.add(entity);
        }
        entity = new ExcelExportEntity();
        entity.setKey("remark");
        entity.setName("备注");
        entity.setWidth(60);
        entities.add(entity);
        PoiUtil.export(response, maps, entities, title);
    }

    @ApiOperation(value = "同步考勤记录")
    @RequiresPermissions("oa:hr:attendance:synchronize")
    @RequestMapping(value = "/synchronize", method = RequestMethod.GET)
    @ResponseBody
    public Object synchronize(Date time) {
        synchronizeNum.getAndIncrement();
        if (synchronizeNum.intValue() > 1) {
            synchronizeNum.getAndDecrement();
            return new OaResult(OaResultConstant.FAILED, "当前或其他用户正在同步，请稍后！");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        try {
            approvalService.countAttendance(year, month);
        } catch (Exception e) {
            _log.error(e.getMessage());
            return new OaResult(OaResultConstant.FAILED, null);
        } finally {
            synchronizeNum.getAndDecrement();
        }
        return new OaResult(OaResultConstant.SUCCESS, null);
    }

    @ApiOperation(value = "同步打卡记录")
    @RequiresPermissions("oa:hr:attendance:synchronize")
    @RequestMapping(value = "/synchronizeCheckInData", method = RequestMethod.GET)
    @ResponseBody
    public Object synchronizeCheckInData(Date time) {
        synchronizeNum.getAndIncrement();
        if (synchronizeNum.intValue() > 1) {
            synchronizeNum.getAndDecrement();
            return new OaResult(OaResultConstant.FAILED, "当前或其他用户正在同步，请稍后！");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        try {
            approvalService.refreshCheckIn(year, month);
        } catch (Exception e) {
            _log.error(e.getMessage());
            return new OaResult(OaResultConstant.FAILED, null);
        } finally {
            synchronizeNum.getAndDecrement();
        }
        return new OaResult(OaResultConstant.SUCCESS, null);
    }

    @RequiresPermissions("oa:hr:attendance:read")
    @RequestMapping(value = "/view", method = RequestMethod.GET)
    public String view(Integer id, Integer year, Integer month, Model model) {
        Calendar calendar = Calendar.getInstance();
        month = month - 1;
        calendar.set(year, month, 1, 0, 0, 0);
        long beginTime = calendar.getTimeInMillis();
        int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(year, month, maxDay, 23, 59, 59);
        long endTime = calendar.getTimeInMillis();

        HrAttendance attendance = attendanceService.selectById(id);
        String userName = attendance.getUserName();
        EntityWrapper<HrCheckin> checkinEntityWrapper = new EntityWrapper<>();
        checkinEntityWrapper.eq("user_name", userName).where("exception_type != ''")
                .eq("state", HrCheckin.UNVERIFIED_STATE)
                .and("checkin_time >=" + beginTime).and("checkin_time <=" + endTime);
        List<HrCheckin> checkins = checkinService.selectList(checkinEntityWrapper);
        //todo 不太好展示
       /* EntityWrapper<HrApproval> approvalEntityWrapper = new EntityWrapper<>();
        approvalEntityWrapper.and("(begin_time >= " + beginTime + " and begin_time < " + endTime + ")" +
                " or (end_time>= " + beginTime + " and end_time <" + endTime + ")")
                .andNew("sp_status =" + HrApproval.PASS_STATUS).andNew().eq("apply_user_name", userName);
        List<HrApproval> leaveApprovals = approvalService.selectList(approvalEntityWrapper);
        approvalEntityWrapper = new EntityWrapper<>();
        approvalEntityWrapper.where("checkin_time >= " + beginTime + " and checkin_time < " + endTime)
                .andNew("sp_status =2").eq("apply_user_name", userName);
        //获取签到审核
        List<HrApproval> checkInApprovals = approvalService.selectList(approvalEntityWrapper);*/
        model.addAttribute("checkins", checkins);
        model.addAttribute("year", year);
        model.addAttribute("month", month);
        return "/manage/hr/attendance/view.jsp";
    }
}
